package com.zoro.barn.business.service.pp.business.project.service;

import com.zoro.barn.business.service.pp.business.product.entity.BarnProduct;
import com.zoro.barn.business.service.pp.business.project.dao.BarnProjectMapper;
import com.zoro.barn.business.service.pp.business.project.entity.BarnProject;
import com.zoro.barn.business.service.pp.business.project.entity.BarnProjectUser;
import com.zoro.barn.business.service.pp.business.projectproduct.entity.BarnProjectProduct;
import com.zoro.barn.business.service.pp.business.projectproduct.mapper.BarnProjectProductMapper;
import com.zoro.barn.business.service.pp.exceptions.DataIncompleteException;
import com.zoro.barn.business.service.pp.server.BarnSqlCopyServerService;
import com.zoro.barn.business.service.pp.server.SqlServiceService;
import com.zoro.barn.business.service.pp.server.facade.BarnDocumentServerServiceFacade;
import com.zoro.barn.commons.tools.string.IDs;
import com.zoro.barn.dto.documentsql.sql.SqlCopyDto;
import com.zoro.barn.dto.documentsql.sql.SqlQueryDto;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhaoxingwu
 */
@Service
public class BarnProjectService {

    @Resource
    private BarnProjectMapper barnProjectMapper;
    @Resource
    private BarnProjectProductMapper projectProductMapper;

    private final SqlServiceService sqlServiceService;
    private final BarnSqlCopyServerService barnSqlCopyServerService;
    private final BarnDocumentServerServiceFacade barnDocumentServerServiceFacade;

    public BarnProjectService(SqlServiceService sqlServiceService, BarnSqlCopyServerService barnSqlCopyServerService,
                              BarnDocumentServerServiceFacade barnDocumentServerServiceFacade) {
        this.sqlServiceService = sqlServiceService;
        this.barnSqlCopyServerService = barnSqlCopyServerService;
        this.barnDocumentServerServiceFacade = barnDocumentServerServiceFacade;
    }


    public List<BarnProject> query(BarnProjectUser barnProject) {
        return this.barnProjectMapper.query(barnProject);
    }

    public BarnProject getById(String pid) {
        return this.barnProjectMapper.selectById(pid);
    }

    @Transactional(rollbackFor = Exception.class)
    public BarnProject insert(BarnProject barnProject) {
        if (StringUtils.isAnyBlank(barnProject.getCreateId(), barnProject.getProjectName())) {
            throw new DataIncompleteException("create id and project name can not be none");
        }
        barnProject.setPid(IDs.uuid());
        barnProject.setCreateTime(new Date());
        this.barnProjectMapper.insert(barnProject);
        return barnProject;
    }


    @Transactional(rollbackFor = Exception.class)
    public BarnProject update(BarnProject barnProject) {
        if (StringUtils.isAnyBlank(barnProject.getPid(), barnProject.getUpdateId(), barnProject.getProjectName())) {
            throw new DataIncompleteException("update id , project name and pid can not be none");
        }
        barnProject.setUpdateTime(new Date());
        this.barnProjectMapper.updateById(barnProject);
        return barnProject;
    }

    public int queryProjectSql(String projectId) {
        SqlQueryDto dto = new SqlQueryDto();
        dto.setProjectId(projectId);
        SqlQueryDto resultDto = sqlServiceService.queryProjectSql(dto);
        return resultDto.getSqlCount() == null ? 0 : resultDto.getSqlCount();
    }

    public int queryProjectDocument(String projectId) {
        return barnDocumentServerServiceFacade.countByProject(projectId);
    }

    /**
     * todo-future 如果这里还需要 clone 文档，那么就可能需要最终事务一致的处理了
     *
     * @param fromProject project that need to be cloned
     * @param toProject   target
     */
    @Transactional
    public void cloneProject(String fromProject, String toProject) {

        BarnProject project = this.barnProjectMapper.selectById(toProject);
        if (project == null) {
            return;
        }

        // 1. 先删除 toProject 原有的
        this.projectProductMapper.deleteProducts(toProject);

        // 2. 再创建新的
        List<BarnProduct> products = this.projectProductMapper.getByProject(fromProject);
        if (CollectionUtils.isNotEmpty(products)) {
            List<BarnProjectProduct> ppList = products.stream().map(v -> {
                BarnProjectProduct pp = new BarnProjectProduct();
                pp.setPid(IDs.uuid());
                pp.setProjectId(toProject);
                pp.setProductId(v.getPid());
                return pp;
            }).collect(Collectors.toList());
            this.projectProductMapper.insertBatch(ppList);
        }
        // 3. 调用 服务 ，clone sql
        SqlCopyDto sqlCopyDto = new SqlCopyDto();
        sqlCopyDto.setFromProjectId(fromProject);
        sqlCopyDto.setToProjectId(toProject);
        sqlCopyDto.setToProjectName(project.getProjectName());
        this.barnSqlCopyServerService.copySql(sqlCopyDto);
    }
}
